home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PsL Monthly 1993 December
/
PSL Monthly Shareware CD-ROM (December 1993).iso
/
prgmming
/
dos
/
pascal
/
p_mat.exe
/
PMATOP.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1993-01-17
|
48KB
|
1,555 lines
{
P-Mat - A Turbo Pascal program for Recursive Matrix Algebra
Version: 1.2
Author: Mark Von Tress, Ph.D.
Date: 01/30/93
Copyright(c) Mark Von Tress 1993
DISCLAIMER: THIS PROGRAM IS PROVIDED AS IS, WITHOUT ANY
WARRANTY, EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
TO FITNESS FOR A PARTICULAR PURPOSE. THE AUTHOR DISCLAIMS
ALL LIABILITY FOR DIRECT OR CONSEQUENTIAL DAMAGES RESULTING
FROM USE OF THIS PROGRAM.
}
Unit pmatop;
Interface
Uses pmat;
Function MSort( a: vmatrixptr; col, order: integer ): vmatrixptr;
Function Mexp( ROp: vmatrixptr ): vmatrixptr;
Function Mabs( ROp: vmatrixptr ): vmatrixptr;
Function Mlog( ROp: vmatrixptr ): vmatrixptr;
Function Msqrt( ROp: vmatrixptr ): vmatrixptr;
Function Trace( ROp: vmatrixptr ): double;
Function Helm( n: integer ): vmatrixptr;
Function Index( lower, upper, step: integer ): vmatrixptr;
Function Kron( a, b: vmatrixptr ): vmatrixptr;
Function Det( Datain: vmatrixptr ): double;
Function Cholesky( ROp: vmatrixptr ): vmatrixptr;
Procedure QR( Var ROp, Q, R: vmatrixptr; makeq: boolean );
Function Svd( Var A, U, S, V: vmatrixptr;
makeu, makev: boolean ) : integer;
Function Ginv( ROp: vmatrixptr ): vmatrixptr;
Function Fft( ROp: vmatrixptr; INZEE: boolean ): vmatrixptr;
Function Vec( ROp: vmatrixptr ): vmatrixptr;
Function Diag( ROp: vmatrixptr ): vmatrixptr;
Function Shape( ROp: vmatrixptr; nrows: integer ): vmatrixptr;
Type margins = (ALL,ROWS,COLUMNS);
Function Sum( ROp: vmatrixptr; marg: margins ) : vmatrixptr;
Function Sumsq( ROp: vmatrixptr; marg: margins ): vmatrixptr;
Function Cusum( ROp: vmatrixptr ): vmatrixptr;
Function Mmax( ROp: vmatrixptr; marg: margins ): vmatrixptr;
Function Mmin( ROp: vmatrixptr; marg: margins ): vmatrixptr;
Procedure Crow( Var ROp: vmatrixptr; row: integer; c: double );
Procedure Srow( Var ROp: vmatrixptr; row1, row2: integer );
Procedure Lrow( Var ROp: vmatrixptr; row1, row2: integer; c: double );
Procedure Ccol( Var ROp: vmatrixptr; col: integer; c: double );
Procedure Scol( Var ROp: vmatrixptr; col1, col2: integer );
Procedure Lcol( Var ROp: vmatrixptr; col1, col2: integer; c: double );
(************************************************************)
Implementation
Procedure heapsort( Var a: vmatrixptr );
Var
n, s0, s1, s2, s3, s4, s5, s4m1, s5m1 : integer;
t1, ts : double;
Begin
{ Shell-Metzger sort, PC-World, May 1986 }
n := a^.r;
s0 := n;
s1 := n;
s1 := s1 Div 2;
While s1 > 0 Do Begin
s2 := s0 - s1;
For s3 := 1 To s2 Do Begin
s4 := s3;
While s4 > 0 Do Begin
s5 := s4 + s1;
s4m1 := s4;
s5m1 := s5;
If a^.m( s4m1, 1 ) > a^.m( s5m1, 1 ) Then Begin
t1 := a^.m( s4m1, 1 );
a^.mm( s4m1, 1 )^ := a^.m( s5m1, 1 );
a^.mm( s5m1, 1 )^ := t1;
ts := a^.m( s4m1, 2 );
a^.mm( s4m1, 2 )^ := a^.m( s5m1, 2 );
a^.mm( s5m1, 2 )^ := ts;
s4 := s4 - s1;
End
Else Begin
s4 := 0;
End;
End;
End;
s1 := s1 Div 2;
End;
End; { end heapsort }
Function MSort{(a :vmatrixptr; col, order: integer): vmatrixptr;};
Var
sorted, temp : vmatrixptr;
i,j,t : integer;
Begin
a^.Garbage;
new( sorted, makematrix( a^.r, a^.c ) );
If order <> 0 Then Begin
{ sort column col, then reorder other rows }
new( temp, makematrix( a^.r, 2 ) );
For i := 1 To a^.r Do Begin
temp^.mm( i, 1 )^ := a^.m( i, col );
temp^.mm( i, 2 )^ := i ;
End;
heapsort( temp );
For i := 1 To a^.r Do Begin
For j := 1 To a^.c Do Begin
t := Trunc( temp^.m( i, 2 ) );
sorted^.mm( i, j )^ := a^.m( t, j );
End;
End;
End
Else Begin
{ sort row col, then reorder other columns }
new( temp, makematrix( a^.c, 2 ) );
For i := 1 To a^.c Do Begin
temp^.mm( i, 1 )^ := a^.m( col, i );
temp^.mm( i, 2 )^ := i ;
End;
heapsort( temp );
For i := 1 To a^.c Do Begin
For j := 1 To a^.r Do Begin
t := Trunc( temp^.m( i, 2 ) );
sorted^.mm( j, i )^ := a^.m( j, t );
End;
End;
End;
Dispatch^.Push( sorted );
dispose( temp, killVmatrix );
MSort := Dispatch^.ReturnMat;
End;
Function Mexp{(ROp :vmatrixptr): vmatrixptr;};
Var
temp : vmatrixptr;
i,j : integer;
Begin
{ take exponent of all elements }
ROp^.Garbage;
new( temp, makematrix( ROp^.r, ROp^.c ) );
For i := 1 To ROp^.r Do Begin
For j := 1 To ROp^.c Do
temp^.mm( i, j )^ := exp( ROp^.m( i, j ) );
End;
Dispatch^.Push( temp );
Mexp := Dispatch^.ReturnMat;
End;
Function Mabs{(ROp: vmatrixptr): vmatrixptr;};
Var
temp : vmatrixptr;
i,j : integer;
Begin
{ take absolute values of all elements }
ROp^.Garbage;
new( temp, makematrix( ROp^.r, ROp^.c ) );
For i := 1 To ROp^.r Do Begin
For j := 1 To ROp^.c Do
temp^.mm( i, j )^ := abs( ROp^.m( i, j ) );
End;
Dispatch^.Push( temp );
Mabs := Dispatch^.ReturnMat;
End;
Function Mlog{(ROp :vmatrixptr): vmatrixptr;};
Var
temp : vmatrixptr;
i,j : integer;
R : double;
Begin
{ take logarithm of all elements }
ROp^.Garbage;
new( temp, makematrix( ROp^.r, ROp^.c ) );
For i := 1 To ROp^.r Do Begin
For j := 1 To ROp^.c Do Begin
R := ROp^.m( i, j );
If R <= 0.0 Then
Dispatch^.Nrerror( 'Mlog: zero or negative argument to log' )
Else temp^.mm( i, j )^ := ln( R );
End;
End;
Dispatch^.Push( temp );
Mlog := Dispatch^.ReturnMat;
End;
Function Msqrt{(ROp: vmatrixptr): vmatrixptr;};
Var
temp : vmatrixptr;
i,j : integer;
R : double;
Begin
{ take sqrt of all elements }
ROp^.Garbage;
new( temp, makematrix( ROp^.r, ROp^.c ) );
For i := 1 To ROp^.r Do Begin
For j := 1 To ROp^.c Do Begin
R := ROp^.m( i, j );
If R < 0 Then
Dispatch^.Nrerror( 'Msqrt: zero or negative argument to sqrt' )
Else temp^.mm( i, j )^ := sqrt( R );
End;
End;
Dispatch^.Push( temp );
Msqrt := Dispatch^.ReturnMat;
End;
Function Trace{(ROp: vmatrixptr): double;};
Var
i : integer;
t : double;
Begin
ROp^.Garbage;
t := 0;
If ROp^.r <> ROp^.c Then
Dispatch^.Nrerror( ' Trace: matrix not square in trace' );
For i := 1 To ROp^.r Do t := t + ROp^.m( i, i );
trace := t;
End;
Function Helm {(n: integer): vmatrixptr;};
Var
i, j : integer;
d, den : double;
temp : vmatrixptr;
Begin
new( temp, makematrix( n, n ) );
For i := 1 To n Do Begin
For j := 1 To n Do Begin
d := 1.0 / sqrt( 0.0 + n );
den := d;
If j > 1 Then den := 1.0 / sqrt( 0.0 + j * (j - 1) );
If (j > 1) And (j < i) Then d := 0;
If (j > 1) And (j = i) Then d := - den * ( 0.0 + (j - 1));
If (j > 1) And (j > i) Then d := den;
temp^.mm( i, j )^ := d;
End;
End;
Dispatch^.Push( temp );
helm := Dispatch^.ReturnMat;
End;
Function Index{( lower, upper, step : integer): vmatrixptr;};
Var
cnter, i : integer;
temp : vmatrixptr;
Begin
If step = 0 Then Dispatch^.Nrerror( 'Index: step is zero' );
cnter := 0;
i := lower;
If lower < upper Then Begin
If step < 0 Then
Dispatch^.Nrerror( 'Index: trying to step from lower to upper with negative step size' );
While i <= upper Do Begin
cnter := cnter + 1;
i := i + step;
End;
End
Else Begin